package com.mzj.saas.mservice.report.service;

import com.mzj.saas.commons.DataConversionUtil;
import com.mzj.saas.commons.ResultBean;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.eligible.entity.DepartmentEnterpriseTagRef;
import com.mzj.saas.mservice.eligible.entity.DepartmentHierarchy;
import com.mzj.saas.mservice.eligible.repository.DepartmentEnterpriseTagRefRepository;
import com.mzj.saas.mservice.eligible.repository.DepartmentHierarchyRepository;
import com.mzj.saas.mservice.report.entity.ReportStatementAccount;
import com.mzj.saas.mservice.report.vo.ReportStatementAccountVO;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReportStatementAccountService {

    /**
     * 在控制台打印日志信息
     */
    private static final Logger log = LoggerFactory.getLogger(ReportStatementAccountService.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private RedisService redisService;

    //机构层级关系设置表
    @Autowired
    private DepartmentHierarchyRepository departmentHierarchyRepository;

    //企业与标签关系表
    @Autowired
    private DepartmentEnterpriseTagRefRepository departmentEnterpriseTagRefRepository;

    /**
     * 列表
     * 根据不同的登录用户标签获取不同的对账单总数据
     * @param accessToken 验证令牌
     * @param pageNumber 起始数据
     * @param pageSize 页面大小
     * @param vo 页面数据
     * @return
     */
    public ResultBean<Map<String ,Object>> pages(String accessToken,Integer pageNumber,Integer pageSize,ReportStatementAccountVO vo){
        log.info("ReportStatementAccountService  pages   accessToken={} , vo={}",accessToken,vo.toString());

        String SQL=" SELECT s.stat_date,s.month_date,SUM(s.wx_online_amount) wx_online_amount,SUM(s.wx_offline_amount) wx_offline_amount, SUM(s.zfb_online_amount) zfb_online_amount ," +
                "SUM(s.zfb_offline_amount) zfb_offline_amount,SUM(s.cash_payment_amount) cash_payment_amount FROM saas_report_statement_account s inner join saas_department d on s.house_property_id=d.id  " ;


        //获取登录用户信息
        TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
        if (tokenRedisVo == null) {
            //未登录提示异常 40001 --- accessToken失效
            return ResultBean.failedResultOfToken();
        }

        //判断用户所属机构是否设置层级架构
        Long enterpriseId = tokenRedisVo.getEnterpriseId();
        DepartmentHierarchy hierarchy = departmentHierarchyRepository.findByOrgIdAndStatus(enterpriseId, 1);
        if (hierarchy == null) {
            //用户所属机构未设置层级架构 10001 --- 用户所属机构未设置层级架构
            return ResultBean.failedResultWithMsg("用户所属机构未设置层级架构");
        }

        //根据机构层级关系id查出企业与标签关系数据
        Long id = hierarchy.getId();
        List<DepartmentEnterpriseTagRef> refs = departmentEnterpriseTagRefRepository.findByDepRefId(id);
        //去重后的用户企业标签
        List<Long> enterpriseTagIds = refs.stream().map(DepartmentEnterpriseTagRef::getTagId).distinct().collect(Collectors.toList());

        //1、政府机构，根据区域标签所对应区域id查
        Long areaTagId = hierarchy.getTagId();//区域标签
        Long areaId = null;
        if (enterpriseTagIds.contains(3L)) {
            areaId = hierarchy.getAreaId();//区域id
        }

        /**
         * 根据不同标签查询不同的业务数据
         */
        String areaTag = "";
        if (areaTagId == 1) {
            areaTag = "province_id";
        } else if (areaTagId == 2) {
            areaTag = "city_id";
        } else if (areaTagId == 3) {
            areaTag = "district_id";
        } else if (areaTagId == 4) {
            areaTag = "street_id";
        } else if (areaTagId == 5) {
            areaTag = "community_id";
        }

        //2、物业
        Long hierarchyOrgId = null;
        if (enterpriseTagIds.contains(4L)) {
            hierarchyOrgId = hierarchy.getOrgId();
        }
        //TODO 上面代码与首页其他查询冗余，可优化

        StringBuilder where = new StringBuilder(" WHERE 1=1 ");
        List<Object> args = new ArrayList<>();

        where.append(" and ( d." + areaTag + " = ? or s.house_property_id = ? ) ");
        args.add(areaId);
        args.add(hierarchyOrgId);

        if(vo != null){

            //月份
            if(StringUtils.isNotBlank(vo.getMonthDate())){
                where.append(" and s.month_date = ?  ");
                args.add(vo.getMonthDate());
            }

        }

        Map<String ,Object> map =new HashMap<>();

        where.append(" GROUP BY s.stat_date ");

        //查询
        List<ReportStatementAccount> data = jdbcTemplate.query(SQL + where, new BeanPropertyRowMapper<>(ReportStatementAccount.class), args.toArray());


        List<ReportStatementAccountVO> resultdata = new ArrayList<>();
        //封装页面展示数据
        for (ReportStatementAccount d : data) {
            ReportStatementAccountVO v = new ReportStatementAccountVO();
            BeanUtils.copyProperties(d,v);
            String moth = d.getStatDate().substring(4,6);
            String day = d.getStatDate().substring(6);
            v.setStatDate(moth+"-"+day);
            //DataConversionUtil.fenToYuan 将分转为元
            v.setWxOnlineAmount(DataConversionUtil.fenToYuan(d.getWxOnlineAmount().toString()));
            v.setWxOfflineAmount(DataConversionUtil.fenToYuan(d.getWxOfflineAmount().toString()));
            v.setZfbOnlineAmount(DataConversionUtil.fenToYuan(d.getZfbOnlineAmount().toString()));
            v.setZfbOfflineAmount(DataConversionUtil.fenToYuan(d.getZfbOfflineAmount().toString()));
            v.setCashPaymentAmount(DataConversionUtil.fenToYuan(d.getCashPaymentAmount().toString()));
            v.setTotal(new BigDecimal(d.getWxOnlineAmount()+d.getWxOfflineAmount()+d.getZfbOnlineAmount()+d.getZfbOfflineAmount()+d.getCashPaymentAmount()).divide(new BigDecimal(100),2,BigDecimal.ROUND_UP));
            resultdata.add(v);
        }

        //月份微信支付(线上)
        BigDecimal monthWxOnlineAmount=new BigDecimal(0);
        //获取月份线上微信支付总和
        Optional<Integer> monthWxOnlineAmountOptional=data.stream().map(ReportStatementAccount::getWxOnlineAmount).reduce(Integer::sum);
        if (monthWxOnlineAmountOptional.isPresent()){
            monthWxOnlineAmount=new BigDecimal(monthWxOnlineAmountOptional.get()) ;
        }

        //月份微信支付(线下)
        BigDecimal monthWxOfflineAmount=new BigDecimal(0);
        //获取月份线下微信支付总和
        Optional<Integer> monthWxOfflineAmountOptional=data.stream().map(ReportStatementAccount::getWxOfflineAmount).reduce(Integer::sum);
        if(monthWxOfflineAmountOptional.isPresent()){
            monthWxOfflineAmount=new BigDecimal(monthWxOfflineAmountOptional.get());
        }

        //月份支付宝支付(线上)
        BigDecimal monthZfbOnlineAmount=new BigDecimal(0);
        //获取月份线上支付宝支付总和
        Optional<Integer> monthZfbOnlineAmountOptional=data.stream().map(ReportStatementAccount::getZfbOnlineAmount).reduce(Integer::sum);
        if(monthZfbOnlineAmountOptional.isPresent()){
            monthZfbOnlineAmount=new BigDecimal(monthZfbOnlineAmountOptional.get());
        }

        //月份支付宝支付(线下)
        BigDecimal monthZfbOfflineAmount=new BigDecimal(0);
        //获取月份线下支付宝支付总和
        Optional<Integer> monthZfbOfflineAmountOptional=data.stream().map(ReportStatementAccount::getZfbOfflineAmount).reduce(Integer::sum);
        if(monthZfbOfflineAmountOptional.isPresent()){
            monthZfbOfflineAmount=new BigDecimal(monthZfbOfflineAmountOptional.get());
        }

        //月份现金
        BigDecimal monthCashPaymentAmount=new BigDecimal(0);
        //获取月份现金支付总和
        Optional<Integer>  monthCashPaymentAmountOptional=data.stream().map(ReportStatementAccount::getCashPaymentAmount).reduce(Integer::sum);
        if(monthCashPaymentAmountOptional.isPresent()){
            monthCashPaymentAmount= new BigDecimal(monthCashPaymentAmountOptional.get());
        }

        //总额
        BigDecimal totalAmount=new BigDecimal(0);

        totalAmount=monthWxOnlineAmount.add(monthWxOfflineAmount).add(monthZfbOnlineAmount).add(monthZfbOfflineAmount).add(monthCashPaymentAmount);

        map.put("data",resultdata);
        //map.put("total",total);

        //DataConversionUtil.fenToYuan 将分转为元
        map.put("monthWxOnlineAmount",DataConversionUtil.fenToYuan(monthWxOnlineAmount.toString()));
        map.put("monthWxOfflineAmount",DataConversionUtil.fenToYuan(monthWxOfflineAmount.toString()));
        map.put("monthZfbOnlineAmount",DataConversionUtil.fenToYuan(monthZfbOnlineAmount.toString()));
        map.put("monthZfbOfflineAmount",DataConversionUtil.fenToYuan(monthZfbOfflineAmount.toString()));
        map.put("monthCashPaymentAmount",DataConversionUtil.fenToYuan(monthCashPaymentAmount.toString()));

        map.put("totalAmount",DataConversionUtil.fenToYuan(totalAmount.toString()));

        return ResultBean.successfulResult(map);
    }


}
